package com.example.PLDroidMediaStreaming;

import android.content.Context;

import com.qiniu.pili.droid.streaming.CameraStreamingSetting;
import com.qiniu.pili.droid.streaming.MicrophoneStreamingSetting;
import com.qiniu.pili.droid.streaming.StreamingProfile;
import com.qiniu.pili.droid.streaming.WatermarkSetting;

import org.json.JSONObject;

import java.util.Map;

public class DataParser {

  StreamingProfile streamingProfile;
  CameraStreamingSetting cameraStreamingSetting;
  MicrophoneStreamingSetting microphoneStreamingSetting;
  WatermarkSetting watermarkSetting;

  DataParser(Map<String, Object> params, Context context) {

    if(hasKey(params,"streamingProfile")) {
      Map<String, Object> sp =  (Map<String, Object>)params.get("streamingProfile");
      parseStreamingProfile(sp);
    }

    if(hasKey(params,"cameraStreamingSetting")) {
      Map<String, Object> css = (Map<String, Object>)params.get("cameraStreamingSetting");
      parseCameraStreamingSetting(css);

    }
    if(hasKey(params,"microphoneStreamingSetting")) {
      Map<String, Object> mss = (Map<String, Object>)params.get("microphoneStreamingSetting");
      parseMicrophoneStreamingSetting(mss);
    }
    if(hasKey(params,"watermarkSetting")) {
      Map<String, Object> ws = (Map<String, Object>)params.get("watermarkSetting");
      parseWatermarkSetting(ws, context);
    }
  }

  private  void parseWatermarkSetting(Map<String, Object> ws, Context context) {
    String absoluteResPath = (String)ws.get("absoluteResPath");
    int resId = (int)ws.get("resId");
    int location = (int)ws.get("location");
    int size = (int)ws.get("size");
    int alpha = (int)ws.get("alpha");

    WatermarkSetting.WATERMARK_LOCATION watermark_location = WatermarkSetting.WATERMARK_LOCATION.values()[location];
    WatermarkSetting.WATERMARK_SIZE watermark_size = WatermarkSetting.WATERMARK_SIZE.values()[size];

    if(absoluteResPath != null) {
      watermarkSetting = new WatermarkSetting(
              context,
              absoluteResPath,
              watermark_location,
              watermark_size,
              alpha
      );
    } else {
      watermarkSetting = new WatermarkSetting(
              context,
              resId,
              watermark_location,
              watermark_size,
              alpha
      );
    }
  }

  private  void parseMicrophoneStreamingSetting(Map<String, Object> mss) {
    microphoneStreamingSetting = new MicrophoneStreamingSetting();
    if(hasKey(mss,"audioPtsOptimizeEnabled")) {
      microphoneStreamingSetting.setAudioPtsOptimizeEnabled(
              (boolean)mss.get("audioPtsOptimizeEnabled")
      );
    }
    if(hasKey(mss,"bluetoothSCOEnabled")) {
      microphoneStreamingSetting.setBluetoothSCOEnabled(
              (boolean)mss.get("bluetoothSCOEnabled")
      );
    }
  }

  static boolean hasKey(Map<String, Object> o, String key) {
    return o.containsKey(key) && o.get(key) != null;
  }

  private void parseStreamingProfile(Map<String, Object> sp) {

    streamingProfile = new StreamingProfile();

    if(hasKey(sp,"aQuality")) {
      int aQuality = (int)sp.get("aQuality");
      streamingProfile.setAudioQuality(aQuality);
    }
    if(hasKey(sp,"vQuality")) {
      int vQuality = (int)sp.get("vQuality");
      streamingProfile.setVideoQuality(vQuality);
    }
    if(hasKey(sp,"encoderRCMode")) {
      int mode = (int)sp.get("encoderRCMode");
      streamingProfile.setEncoderRCMode(
              StreamingProfile.EncoderRCModes.values()[mode]
      );
    }
    if(hasKey(sp,"orientation")) {
      int orientation = (int)sp.get("orientation");
      streamingProfile.setEncodingOrientation(
              StreamingProfile.ENCODING_ORIENTATION.values()[orientation]
      );
    }
    if(hasKey(sp,"publishUrl")) {
      String publishUrl = (String)sp.get("publishUrl");
      try {
        streamingProfile.setPublishUrl(publishUrl);
      } catch (Exception e) {

      }
    }

    if(hasKey(sp,"avProfile")) {
      Map<String, Object> av = (Map<String, Object>)sp.get("avProfile");
      Map<String, Object> vp = (Map<String, Object>)av.get("videoProfile");
      Map<String, Object> ap = (Map<String, Object>)av.get("audioProfile");

      StreamingProfile.VideoProfile videoProfile = new StreamingProfile.VideoProfile(
              (int)vp.get("reqFps"),
              (int)vp.get("reqBitrate")
      );

      StreamingProfile.AudioProfile audioProfile = new StreamingProfile.AudioProfile(
              (int)ap.get("reqBitrate"),
              (int)ap.get("sampleRate")
      );

      StreamingProfile.AVProfile avProfile = new StreamingProfile.AVProfile(videoProfile, audioProfile);
      streamingProfile.setAVProfile(avProfile);
    }

    if(hasKey(sp,"videoEncodingSize")) {
      Map<String, Object> ves = (Map<String, Object>)sp.get("videoEncodingSize");
      if(hasKey(ves,"level")) {
        streamingProfile.setEncodingSizeLevel(
                (int)ves.get("level")
        );
      }
    }
    if(hasKey(sp,"ssConfig")) {
      Map<String, Object> ssc = (Map<String, Object>)sp.get("ssConfig");
      if(hasKey(ssc,"intervalMs")) {
        streamingProfile.setStreamStatusConfig(
                new StreamingProfile.StreamStatusConfig(
                        (int)ssc.get("intervalMs")
                )
        );
      }
    }
    if(hasKey(sp,"stream")) {
      Map<String, Object> map = (Map<String, Object>)sp.get("stream");
      JSONObject jsonObject = new JSONObject();
      for(Map.Entry<String, Object> entry : map.entrySet()){
        try {
          jsonObject.put(entry.getKey(), entry.getValue());
        } catch (Exception e) {

        }
      }
      streamingProfile.setStream(new StreamingProfile.Stream(jsonObject));
    }

    if(hasKey(sp,"sendTimeout")) {
      streamingProfile.setSendTimeoutInSecond(
              (int)sp.get("sendTimeout")
      );
    }

    if(hasKey(sp,"bufferInfo")) {
      streamingProfile.setSendingBufferProfile(
              new StreamingProfile.SendingBufferProfile(
                      (float)sp.get("lowThreshold"),
                      (float)sp.get("highThreshold"),
                      (float)sp.get("durationLimit"),
                      (int)sp.get("lowThresholdTimeout")
              )
      );
    }
  }

  private void parseCameraStreamingSetting(Map<String, Object> css) {
    cameraStreamingSetting = new CameraStreamingSetting();
    if(hasKey(css,"cameraId")) {
      cameraStreamingSetting.setCameraId(
              (int)css.get("cameraId")
      );
    }
    if(hasKey(css,"continuousFocusModeEnabled")) {
      cameraStreamingSetting.setContinuousFocusModeEnabled(
              (boolean)css.get("continuousFocusModeEnabled")
      );
    }
    if(hasKey(css,"focusMode")) {
      cameraStreamingSetting.setFocusMode(
              (String)css.get("focusMode")
      );
    }
    if(hasKey(css,"frontCameraMirror")) {
      cameraStreamingSetting.setFrontCameraMirror(
              (boolean)css.get("frontCameraMirror")
      );
    }
    if(hasKey(css,"recordingHint")) {
      cameraStreamingSetting.setRecordingHint(
              (boolean)css.get("recordingHint")
      );
    }
    if(hasKey(css,"resetTouchFocusDelayInMs")) {
      cameraStreamingSetting.setResetTouchFocusDelayInMs(
              (int)css.get("resetTouchFocusDelayInMs")
      );
    }
    if(hasKey(css,"cameraPreviewSize")) {
      Map<String, Object> cps = (Map<String, Object>)css.get("cameraPreviewSize");
      if(hasKey(cps,"level")) {
        int level = (int)cps.get("level");
        cameraStreamingSetting.setCameraPrvSizeLevel(
                CameraStreamingSetting.PREVIEW_SIZE_LEVEL.values()[level]
        );
      }
      if(hasKey(cps,"ratio")) {
        int level = (int)cps.get("ratio");
        cameraStreamingSetting.setCameraPrvSizeRatio(
                CameraStreamingSetting.PREVIEW_SIZE_RATIO.values()[level]
        );
      }
    }
  }
}
